# coding: utf-8
#
# Copyright (c) Microsoft Corporation.  All rights reserved.
#
##
# Module containing classes to generate files and directories in a target
# directory in various ways.
#
# Date:   2007-09-25 13:45:34
#

import scxutil
import os

##
# Base class for file generator classes 
#
class StagedObject:
    ##
    # Ctor.
    # \param[in] path Path of item relative to target root directory.
    # \param[in] permissions File permissions.
    # \param[in] owner File owner.
    # \param[in] group File group.
    # \param[in] fileType 'file', 'conffile', 'dir', 'sysdir' or 'link'
    #
    def __init__(self, path, permissions, owner, group, fileType):
        self.path = path
        self.permissions = permissions
        self.owner = owner
        self.group = group
        self.fileType = fileType

    ##
    # Sets the target root directory.
    # \param[in] rootDir Absolute path to root directory.
    #
    def SetRootDir(self, rootDir):
        self.rootDir = rootDir

    ##
    # Create the file. In the base class this implementation is empty.
    #
    def DoCreate(self) :
        pass

    ##
    # Get the file path (relative to root dir).
    # \returns path
    #
    def GetPath(self) :
        return self.path

    ##
    # Set the file path (relative to root dir).
    # \param[in] path
    #
    def SetPath(self, path) :
        self.path = path

    ##
    # Get the file permissions
    # \returns File permissions
    #
    def GetPermissions(self) :
        return self.permissions

    ##
    # Get the file owner
    # \returns File owner
    #
    def GetOwner(self) :
        return self.owner

    ##
    # Get the file group
    # \returns File group
    #
    def GetGroup(self) :
        return self.group

    ##
    # Get the file type.
    # \returns File type ('file', 'conffile', 'dir', 'sysdir' or 'link')
    #
    def GetFileType(self) :
        return self.fileType

##
# File that is generated by being copied from a source location.
#
class FileCopy(StagedObject):
    ##
    # Ctor.
    # \param[in] path Path of target file relative to target root directory.
    # \param[in] srcPath Path of source file relative to source root directory.
    # \param[in] permissions File permissions.
    # \param[in] owner File owner.
    # \param[in] group File group.
    # \param[in] fileType 'file' or 'conffile'
    #
    def __init__(self, path, srcPath, permissions, owner, group, fileType = 'file'):
        StagedObject.__init__(self, path, permissions, owner, group, fileType)
        self.srcPath = srcPath

    ##
    # Set source directory root.
    # \param[in] rootDir Absolute path to source directory root.
    #
    def SetSrcRootDir(self, rootDir):
        self.srcRootDir = rootDir
        
    ##
    # Set the source file path (relative to source root dir).
    # \param[in] path
    #
    def SetSrcPath(self, path) :
        self.srcPath = path

    ##
    # Set the source file path (relative to source root dir).
    # \returns source path relative to source root dir.
    #
    def GetSrcPath(self) :
        return self.srcPath

    ##
    # Create the file. Copies the file from source to dest.
    #
    def DoCreate(self) :
        scxutil.Copy(os.path.join(self.srcRootDir, self.srcPath),
                     os.path.join(self.rootDir, self.path))

##
# File that is created empty in the staging directory
#
class EmptyFile(StagedObject):
    ##
    # Ctor.
    # \param[in] path Path of target file relative to target root directory.
    # \param[in] permissions File permissions.
    # \param[in] owner File owner.
    # \param[in] group File group.
    # \param[in] fileType 'file' or 'conffile'
    #
    def __init__(self, path, permissions, owner, group, fileType = 'file'):
        StagedObject.__init__(self, path, permissions, owner, group, fileType)

    ##
    # Create the file. Creates an empty file.
    #
    def DoCreate(self) :
        scxutil.Touch(os.path.join(self.rootDir, self.path))


##
# Soft link that is generated in the destination directory
#
class SoftLink(StagedObject):
    ##
    # Ctor.
    # \param[in] path Path of soft link relative to target root directory.
    # \param[in] lnPath Path of link target.
    # \param[in] permissions File permissions.
    # \param[in] owner File owner.
    # \param[in] group File group.
    #
    def __init__(self, path, lnPath, permissions, owner, group):
        StagedObject.__init__(self, path, permissions, owner, group, 'link')
        self.lnPath = lnPath
        
    ##
    # Set source directory root.
    # \param[in] rootDir Absolute path to source directory root.
    #
    def SetSrcRootDir(self, rootDir):
        pass

    ##
    # Get the link target.
    # \returns Link target
    #
    def GetTarget(self):
        return self.lnPath

    ##
    # Set the link target.
    # \patam[in] target Link target
    #
    def SetTarget(self, target):
        self.lnPath = target

    ##
    # Create the file. Copies the file from source to dest.
    #
    def DoCreate(self) :
        scxutil.Link(self.lnPath, os.path.join(self.rootDir, self.path))


##
# Directory that is created new.
#
class NewDirectory(StagedObject):
    ##
    # Ctor.
    # \param[in] path Path of target directory relative to target root directory.
    # \param[in] permissions File permissions.
    # \param[in] owner File owner.
    # \param[in] group File group.
    # \param[in] fileType 'dir' or 'sysdir'
    #
    def __init__(self, path, permissions, owner, group, fileType = 'dir'):
        StagedObject.__init__(self, path, permissions, owner, group, fileType)

    ##
    # Create the directory.
    #
    def DoCreate(self) :
        scxutil.MkDir(os.path.join(self.rootDir, self.path))


##
# Directory that is created new.
#
class DirectoryCopy:
    ##
    # Ctor.
    # \param[in] path Path of target directory relative to target root directory.
    # \param[in] srcPath Absolute path of source directory.
    # \param[in] permissions File permissions of all destination files and directories.
    # \param[in] owner File owner.
    # \param[in] group File group.
    #
    def __init__(self, path, srcPath, permissions, owner, group):
        self.path = path
        self.srcPath = srcPath
        self.permissions = permissions
        self.owner = owner
        self.group = group
        self.directories = []
        self.files = []
        self.PopulateLists("")

    ##
    # Populate self.directories and self.files
    # \param[in] subpath Relative path. Used recursively.
    #
    def PopulateLists(self, subpath):
        targetPath = os.path.join(self.path, subpath)
        dirObject = NewDirectory(targetPath, self.permissions, self.owner, self.group)
        self.directories.append(dirObject)
        
        sourcePath = os.path.join(self.srcPath, subpath)
        names = os.listdir(sourcePath)
        for name in names:
            filePath = os.path.join(sourcePath, name)
            if os.path.isdir(filePath):
                self.PopulateLists(os.path.join(subpath, name))
            elif os.path.isfile(filePath):
                fileCopy = FileCopy(os.path.join(targetPath, name), os.path.join(subpath, name), self.permissions, self.owner, self.group)
                fileCopy.SetSrcRootDir(self.srcPath)
                self.files.append(fileCopy)

    ##
    # Returns a list of NewDirectory objects. One object for each of the directories in srcPath.
    #
    def GetDirectoryList(self) :
        return self.directories

    ##
    # Returns a list of FileCopy objects. One object for each of the files in srcPath.
    #
    def GetFileList(self) :
        return self.files




